<template>
  <!-- <transition name="toast"> -->
  <div v-show="isShow" :key="activeToastId" class="active-toasts" :style="activeToastsStyle">
    <template v-for="(item, index) in activeToasts">
      <template v-show="item">
        <toast-item
          :key="`${index}`"
          :left="0"
          :top="caclToastTop(0, index, toastHeight)"
          :z-index="1"
          :height="height"
          :font-size="fontSize"
          :background-color="backgroundColor"
          :color="color"
          :content="item ? item.message : ''"
        />
      </template>
    </template>
  </div>
  <!-- </transition> -->
</template>

<script>
import { mapState } from 'vuex'
import { makeUUID } from '@/utils'
import ToastItem from './item'

// https://blog.csdn.net/qq_41422946/article/details/104344246
export default {
  name: 'Toast',
  components: { ToastItem },
  props: {
    left: {
      type: Number,
      required: false,
      default: 0
    },
    top: {
      type: Number,
      required: false,
      default: 0
    },
    toastHeight: {
      type: Number,
      required: false,
      default: 24
    },
    fontSize: {
      type: Number,
      required: false,
      default: 12
    },
    // 注: ocx颜色是bgr, css颜色是rgbz
    backgroundColor: {
      type: String,
      required: false,
      default: 'transparent'
    },
    color: {
      type: String,
      required: false,
      default: '#000000'
    },
    zIndex: {
      type: Number,
      required: false,
      default: 10
    },
    toastBuffer: {
      type: Number,
      required: false,
      default: 40
    },
    // 活动toast个数
    toastActives: {
      type: Number,
      required: false,
      default: 3
    },
    // 多少秒之后隐藏
    duration: {
      type: Number,
      required: false,
      default: 3
    }
  },
  data() {
    return {
      // 是否隐藏
      isShow: true,
      // 定时器id
      timerId: null,
      // 活动toast数组
      activeToasts: new Array(this.toastActives),
      // toast缓冲数组
      bufferToasts: new Array(this.toastBuffer),
      // 活动toast id
      activeToastId: '',
      firstPos: 0,
      lastPos: 0
    }
  },
  computed: {
    ...mapState('editor/diagram', {
      toastQueue: 'toastQueue',
      toastState: 'toastState',
      newToasts: 'newToasts',
      TOAST_CLOSE: 'TOAST_CLOSE'
    }),
    readToClose() {
      return this.toastState === this.TOAST_CLOSE
    },
    activeToastsStyle() {
      return {
        left: `${this.left}px`,
        top: `${this.top}px`,
        zIndex: this.zIndex,
        backgroundColor: this.backgroundColor,
        color: this.color
      }
    }
    // activeToasts() {
    //   return this.bufferToasts.slice(this.firstPos, this.lastPos)
    // }
  },
  watch: {
    toastState(val) {
      // 如果没有收到关闭指令
      if (val !== this.TOAST_CLOSE) {
        // 取消定时器
        this.cancelTimer()
        // 保持显示状态
        this.isShow = true
        // 如果id=''，重新生成id
        if (this.activeToastId === '') {
          this.activeToastId = makeUUID()
        }

        // console.log(
        //   'xxxx:',
        //   this.firstPos,
        //   this.lastPos,
        //   this.newToasts,
        //   this.bufferToasts.length
        // )
        // toast消息已全部显示
        if (this.firstPos === this.bufferToasts.length) {
          // 全部清空
          for (let i = 0; i < this.bufferToasts.length; i++) {
            this.$set(this.bufferToasts, i, null)
          }
          this.firstPos = 0
          this.lastPos = 0
        }
        // first指针前进一位
        if (
          this.firstPos >= 0 &&
          this.lastPos - this.firstPos >= this.toastActives
        ) {
          this.$set(this.bufferToasts, this.firstPos, null)
          this.firstPos += 1
        }
        // 接收的toast消息个数超出缓冲数组范围
        if (this.lastPos + this.newToasts > this.bufferToasts.length) {
          // 全部移动到开始位置
          const arr = this.bufferToasts.slice(this.firstPos, this.lastPos)
          for (let i = 0; i < this.bufferToasts.length; i++) {
            this.$set(this.bufferToasts, i, null)
          }
          this.firstPos = 0
          this.lastPos = 0
          arr.forEach(item => {
            this.$set(this.bufferToasts, this.lastPos, item)
            this.lastPos += 1
          })
        }
        // 接收toast, last指针继续累加
        this.toastQueue.slice(-1 * this.newToasts).forEach(item => {
          if (this.lastPos < this.bufferToasts.length) {
            this.$set(this.bufferToasts, this.lastPos, item)
            this.lastPos += 1
          }
        })

        // 更新activeToasts
        const that = this
        this.$nextTick(() => {
          that.updateActiveToasts()
        })
      }
    },
    readToClose(newVal, oldVal) {
      // 收到关闭指令, 启动定时器, 3s后隐藏组件
      if (newVal && !oldVal) {
        this.startTimer()
      }
    }
  },
  created() {
    this.init()
  },
  beforeDestroy() {
    this.cancelTimer()
  },
  methods: {
    init() {
      this.firstPos = 0
      this.lastPos = 0
      for (let i = 0; i < this.bufferToasts.length; i++) {
        this.bufferToasts[i] = null
      }
    },
    caclToastTop(top, i, height) {
      // console.log(top, i, height)
      return top + i * height
    },
    updateActiveToasts() {
      for (let i = 0; i < this.activeToasts.length; i++) {
        this.$set(this.activeToasts, i, null)
      }
      // 更新activeToasts
      let n = this.lastPos - this.firstPos
      if (n > this.activeToasts.length) n = this.activeToasts.length
      for (let j = 0; j < n; j++) {
        this.$set(this.activeToasts, j, this.bufferToasts[this.firstPos + j])
      }
    },
    startTimer() {
      const that = this
      this.timerId = setTimeout(() => {
        that.isShow = false
        that.activeToastId = ''
        // that.activeToasts = []
        this.init()
      }, that.duration * 1000)
    },
    cancelTimer() {
      if (this.timerId) {
        clearTimeout(this.timerId)
        this.timerId = 0
      }
    }
  }
}
</script>

<style lang="scss" scoped>
.active-toasts {
  position: absolute;
  z-index: 10;
  left: 5px;
  top: 0px;
  background-color: #212830;
  width: auto;
  height: auto;
  pointer-events: none;
}

// .toast-enter-active,
.toast-leave-active {
  transition: all 3s;
}

// .toast-enter,
.toast-leave-to {
  opacity: 1;
}

// .toast-enter-to,
.toast-leave {
  opacity: 0;
}
</style>
